# from django.shortcuts import render

# # Create your views here.





from django.shortcuts import render, get_object_or_404
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView
from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin
from django.urls import reverse_lazy
from django.db.models import Count, Q, F
from django.core.cache import cache
from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_page
from django.views.decorators.vary import vary_on_cookie
from django.http import JsonResponse
from django.contrib import messages
from django.db import transaction
from django.views import View
from .models import Book, Author, Publisher, BookLoan, BookReview
from .forms import BookForm, AuthorForm, BookLoanForm
from .signals import book_published, book_returned
import logging

logger = logging.getLogger(__name__)

# 基于类的视图
class BookListView(ListView):
    model = Book
    template_name = 'books/book_list.html'
    context_object_name = 'books'
    paginate_by = 10
    
    def get_queryset(self):
        queryset = super().get_queryset()
        status = self.request.GET.get('status')
        if status:
            queryset = queryset.filter(status=status)
        return queryset.select_related('author', 'publisher')
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['status_choices'] = Book.STATUS_CHOICES
        return context

@method_decorator(cache_page(60 * 15), name='dispatch')
@method_decorator(vary_on_cookie, name='dispatch')
class BookDetailView(DetailView):
    model = Book
    template_name = 'books/book_detail.html'
    context_object_name = 'book'
    
    def get_object(self, queryset=None):
        book_id = self.kwargs.get('pk')
        cache_key = f'book_{book_id}_details'
        book = cache.get(cache_key)
        if not book:
            book = super().get_object(queryset)
            cache.set(cache_key, book, 60 * 60)  # 缓存1小时
        return book

class BookCreateView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
    model = Book
    form_class = BookForm
    template_name = 'books/book_form.html'
    permission_required = 'books.add_book'
    success_url = reverse_lazy('book-list')
    
    def form_valid(self, form):
        response = super().form_valid(form)
        if form.instance.status == 'published':
            book_published.send(
                sender=self.model,
                book=form.instance,
                publisher=form.instance.publisher
            )
        return response

class BookUpdateView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
    model = Book
    form_class = BookForm
    template_name = 'books/book_form.html'
    permission_required = 'books.change_book'
    
    def get_success_url(self):
        return reverse_lazy('book-detail', kwargs={'pk': self.object.pk})

class BookDeleteView(LoginRequiredMixin, PermissionRequiredMixin, DeleteView):
    model = Book
    template_name = 'books/book_confirm_delete.html'
    permission_required = 'books.delete_book'
    success_url = reverse_lazy('book-list')

# 自定义中间件
class BookMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
    
    def __call__(self, request):
        # 请求处理前的逻辑
        if 'book' in request.path:
            logger.info(f"Accessing book-related page: {request.path}")
        
        response = self.get_response(request)
        
        # 响应处理后的逻辑
        if 'book' in request.path:
            logger.info(f"Completed book-related request: {request.path}")
        
        return response

# 基于函数的视图
@cache_page(60 * 5)
def author_detail(request, pk):
    author = get_object_or_404(Author.objects.prefetch_related('books'), pk=pk)
    return render(request, 'books/author_detail.html', {'author': author})

# API视图
class BookAPIView(View):
    def get(self, request, *args, **kwargs):
        books = Book.objects.all().values('id', 'title', 'author__name', 'publish_date')
        return JsonResponse(list(books), safe=False)

# 事务处理视图
class LoanBookView(LoginRequiredMixin, View):
    def post(self, request, *args, **kwargs):
        book_id = kwargs.get('pk')
        book = get_object_or_404(Book, pk=book_id)
        
        with transaction.atomic():
            savepoint = transaction.savepoint()
            try:
                loan = BookLoan(book=book, user=request.user)
                loan.full_clean()
                loan.save()
                messages.success(request, f"You have successfully borrowed {book.title}")
            except Exception as e:
                transaction.savepoint_rollback(savepoint)
                messages.error(request, f"Error borrowing book: {str(e)}")
                logger.error(f"Error borrowing book: {str(e)}")
        
        return redirect('book-detail', pk=book_id)

# 批量操作视图
class BulkUpdatePricesView(LoginRequiredMixin, PermissionRequiredMixin, View):
    permission_required = 'books.change_book'
    
    def post(self, request, *args, **kwargs):
        book_ids = request.POST.getlist('book_ids')
        price_increase = float(request.POST.get('price_increase', 0))
        
        try:
            Book.bulk_update_prices(book_ids, price_increase)
            messages.success(request, f"Updated prices for {len(book_ids)} books")
        except Exception as e:
            messages.error(request, f"Error updating prices: {str(e)}")
        
        return redirect('book-list')